﻿#region Header

// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------

#endregion

#region Usings

using System;
using System.IO;
using System.Reflection;

#endregion

namespace ScrumTable.Common.FileSystem
{
    /// <summary>
    /// Represents an utility class for folder handling.
    /// </summary>
    public static class DataFolderUtil
    {
        #region Declarations

        /// <summary>
        /// Gets the physical assembly directory path (absolute).
        /// </summary>
        public static readonly string AssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

        /// <summary>
        /// Gets the data path below the physical assembly directory.
        /// </summary>
        public static readonly string AssemblyBasedDataFolder = Path.Combine(AssemblyDirectory, DataFolderName);

        /// <summary>
        /// Gets the config path below the physical assembly directory.
        /// </summary>
        public static readonly string AssemblyBasedConfigFolder = Path.Combine(AssemblyDirectory, ConfigFolderName);

        private const string AppFolderName = "Surface";
        private const string ConfigFolderName = "Config";
        private const string DataFolderName = "Data";

        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------
        
        #endregion

        #region Constructors / Destructor

        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        #endregion

        #region Methods

        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the application data (Environment.SpecialFolder.ApplicationData)
        /// folder path of the current application.
        /// </summary>
        /// <returns>Returns the evaluated path.</returns>
        public static string GetApplicationDataFolder()
        {
            string path = Path.Combine(Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData), AppFolderName);
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            return path;
        }

        /// <summary>
        /// Gets the configuration file path below the current executing assembly
        /// path or below the application data folder.
        /// </summary>
        /// <param name="name">Name of the settings path to search below the application data folder.</param>
        /// <returns>If a folder with the  given name exists below the
        /// application data folder this folder path will be returned.
        /// Otherwise you will obtain the "config" folder path below the
        /// executing assembly.</returns>
        public static string GetConfigFile(string name)
        {
            string path = GetConfigUserPath(name);
            if (!File.Exists(path))
            {
                path = Path.Combine(AssemblyBasedConfigFolder, name);
            }
            return path; 
        }

        /// <summary>
        /// Returns the path to the config file/folder in the user directory.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetConfigUserPath(string name)
        {
            return Path.Combine(GetApplicationDataFolder(), name);
        }

        /// <summary>
        /// Gets the file path of the application data (AppData) folder.
        /// </summary>
        public static string GetDataPath()
        {
            return Path.Combine(GetApplicationDataFolder(), DataFolderName);
        }

        /// <summary>
        /// Gets the config file path of the application data (AppData) folder.
        /// </summary>
        public static string GetConfigPath()
        {
            return Path.Combine(GetApplicationDataFolder(), ConfigFolderName);
        }

        /// <summary>
        /// Gets the data file path below the current executing assembly
        /// path or below the application data folder.
        /// </summary>
        /// <param name="name">Name of the settings path to search below the application data folder.</param>
        /// <returns>If a folder with the  given name exists below the
        /// application data folder this folder path will be returned.
        /// Otherwise you will obtain the "data" folder path below the
        /// executing assembly.</returns>
        public static string GetDataFile(string name)
        {
            string path = Path.Combine(GetDataPath(), name);
            if (!File.Exists(path))
            {
                path = Path.Combine(AssemblyBasedDataFolder, name);
            }
            return path;
        }

        /// <summary> 
        /// Gets a path for a relative path for uploading a file (example: Attachments)
        /// </summary>
        /// <returns></returns>
        public static string GetTempUploadFileRelative()
        {
            return "Upload";
        }

        /// <summary> 
        /// Gets a path for a absolute path for uploading a file (example: Attachments)
        /// </summary>
        /// <returns></returns>
        public static string GetTempUploadFileAbsolute()
        {
            string directoryPathAbs = Path.Combine(GetApplicationDataFolder(), GetTempUploadFileRelative());

            if (!Directory.Exists(directoryPathAbs))
            {
                Directory.CreateDirectory(directoryPathAbs);
            }
            return directoryPathAbs;
        }

        /// <summary>
        /// Creates a new random Directory in the temp file system folder.
        /// </summary>
        /// <returns>Returns the directory info about the created folder.</returns>
        public static DirectoryInfo CreateRandomFolderInTemp()
        {
            return CreateRandomFolderInTemp(Guid.NewGuid().ToString("D"));
        }

        /// <summary>
        /// Creates a new random Directory in the temp file system folder.
        /// </summary>
        /// <returns>Returns the directory info about the created folder.</returns>
        public static DirectoryInfo CreateRandomFolderInTemp(string randomKey)
        {
            string randomFolder = Path.Combine(
                Environment.GetEnvironmentVariable("TEMP"),
                randomKey);

            DirectoryInfo directoryInfo = new DirectoryInfo(randomFolder);

            if (!directoryInfo.Exists)
            {
                directoryInfo.Create();
            }
            return directoryInfo;
        }

        #endregion

        #region Events

        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}